import { Injectable, NotFoundException } from '@nestjs/common';
import { UpdateShareDto } from './dto/update-share.dto';
import { CreateShareDto } from './dto/create-share.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Share } from './entities/share.entity';
import { UserToShare } from './entities/usertoshare.entity';
import { In, Repository } from 'typeorm';
import { CreateUserToShareDto } from './dto/create-usertoshare.dto';
import { User } from 'src/user/entities/user.entity';
import { CreateGroupToShareDto } from './dto/create-grouptoshare.dto';
import { Group } from 'src/group/entities/group.entity';
import { GroupToShare } from './entities/grouptoshare.entity';
import { usertogroup } from 'src/group/entities/usertogroup.entity';

@Injectable()
export class ShareService {
  constructor(
    @InjectRepository(Share)
    private readonly shareRepository: Repository<Share>,
    @InjectRepository(UserToShare)
    private readonly userToShareRepository: Repository<UserToShare>,
    @InjectRepository(GroupToShare)
    private readonly groupToShareRepository: Repository<GroupToShare>,
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    @InjectRepository(Group)
    private readonly groupRepository: Repository<Group>,
    @InjectRepository(usertogroup)
    private readonly usertogroupRepository: Repository<usertogroup>,
  ) {}
  async createShare(createShareDto: CreateShareDto) {
    const insertShare = await this.shareRepository.insert(
      this.shareRepository.create(createShareDto),
    );
    const userInfo = await this.userRepository.findOne({
      where: { email: createShareDto.belong },
    });
    const createUserToShareDto = new CreateUserToShareDto();
    createUserToShareDto.type = 'send';
    createUserToShareDto.shareuuid = insertShare.raw[0].id;
    createUserToShareDto.useruuid = userInfo.id;
    const insertResearch = await this.userToShareRepository.insert(
      this.userToShareRepository.create(createUserToShareDto),
    );
    return insertShare.raw[0].id;
  }

  createUserToShare(createUserToShareDto: CreateUserToShareDto) {
    this.userToShareRepository.insert(
      this.userToShareRepository.create(createUserToShareDto),
    );
    return '';
  }

  getAllShares() {
    // 此接口好像无意义
    return this.shareRepository.find();
  }
  getShareItemById(id: string) {
    return this.shareRepository.findOne({ where: { id: id } });
  }
  async checkShareById(id: string) {
    const checkRes = await this.getShareItemById(id);
    if (checkRes === null) {
      return false;
    } else {
      return true;
    }
  }
  async checkShareByScenceuuid(scenceuuid: string) {
    const checkRes = await this.shareRepository.findOne({
      where: { scenceuuid: scenceuuid },
    });
    if (checkRes === null) {
      return;
    } else {
      return checkRes;
    }
  }
  async checkOnceReceiveShareByShareuuid(shareuuid: string, useruuid: any) {
    const checkRes = await this.userToShareRepository.findOne({
      where: { shareuuid: shareuuid, useruuid: useruuid },
    });
    if (checkRes === null) {
      return true;
    } else {
      return false;
    }
  }
  async getSendShareItemByUser(email: string) {
    const userInfo = await this.userRepository.findOne({
      where: { email: email },
    });

    if (!userInfo) {
      throw new Error('User not found');
    }

    const sendUserToShareList = await this.userToShareRepository.find({
      where: { useruuid: userInfo.id, type: 'send' },
    });

    const shareUuids = sendUserToShareList.map((item) => item.shareuuid);

    const result = await Promise.all(
      shareUuids.map((uuid) => this.getShareItemById(uuid)),
    );
    return result;
  }
  async getReceiveShareItemByUser(email: string) {
    // Fetch user info by email
    const userInfo = await this.userRepository.findOne({
      where: { email: email },
    });

    if (!userInfo) {
      throw new Error('User not found');
    }

    // Fetch the share list where the user is the receiver
    const sendUserToShareList = await this.userToShareRepository.find({
      where: { useruuid: userInfo.id, type: 'receive' },
    });
    const shareUuids = sendUserToShareList.map((item) => item.shareuuid);

    if (shareUuids.length === 0) {
      return [];
    }

    // Fetch all share items and their corresponding user info in parallel
    const shareItems = await this.getShareItemsByIds(shareUuids);
    const userEmails = shareItems.map((item) => item.belong);
    const users = await this.userRepository.find({
      where: { email: In(userEmails) },
    });

    const userMap = new Map(users.map((user) => [user.email, user.username]));

    // Map share items to include the user's username
    const result = shareItems.map((shareInfo) => ({
      ...shareInfo,
      belong: userMap.get(shareInfo.belong) || 'Unknown',
    }));

    return result;
  }

  private async getShareItemsByIds(uuids: string[]) {
    return await Promise.all(uuids.map((uuid) => this.getShareItemById(uuid)));
  }
  async updateShareItemById(id: string, updateShareDto: UpdateShareDto) {
    const result = await this.shareRepository.update(id, updateShareDto);
    if (result.affected === 0) {
      throw new NotFoundException(`Picture with ID "${id}" not found.`);
    }
  }
  async removeShareItemById(id: string) {
    try {
      const delList = await this.userToShareRepository.find({
        where: { shareuuid: id },
      });

      // 并行删除所有 UserToShareItem
      await Promise.all(
        delList.map((item) => this.removeUserToShareItemById(item.id)),
      );

      // 删除 shareRepository 中的项
      await this.shareRepository.delete({ id: id });

      return '删除成功';
    } catch (error) {
      console.error('删除失败:', error);
      return '删除失败';
    }
  }
  removeUserToShareItemById(id: string) {
    try {
      return this.userToShareRepository.delete({ id: id });
    } catch (error) {
      return `删除失败`;
    }
  }
  removeUserToShareItemByShareId(shareId: string, useruuid: string) {
    try {
      return this.userToShareRepository.delete({
        shareuuid: shareId,
        useruuid: useruuid,
        type: 'receive',
      });
    } catch (error) {
      return `删除失败`;
    }
  }
  // group 相关接口
  async createShareByGroup(createShareDto: CreateShareDto, email: string) {
    const insertShare = await this.shareRepository.insert(
      this.shareRepository.create(createShareDto),
    );
    const groupInfo = await this.groupRepository.findOne({
      where: { group_id: createShareDto.belong },
    });
    const createGroupToShareDto = new CreateGroupToShareDto();
    createGroupToShareDto.type = 'send';
    createGroupToShareDto.shareuuid = insertShare.raw[0].id;
    createGroupToShareDto.groupuuid = groupInfo.id;
    createGroupToShareDto.sharer = email;
    const insertResearch = await this.groupToShareRepository.insert(
      this.groupToShareRepository.create(createGroupToShareDto),
    );
    return insertShare.raw[0].id;
  }
  createGroupToShare(createGroupToShareDto: CreateGroupToShareDto) {
    this.groupToShareRepository.insert(
      this.groupToShareRepository.create(createGroupToShareDto),
    );
    return '';
  }
  async checkOnceReceiveShareGroupByShareuuid(
    checkJsonData: {
      shareuuid: string;
      groupuuid: string;
    },
    useruuid: string,
  ) {
    const checkRes = await this.groupToShareRepository.findOne({
      where: {
        shareuuid: checkJsonData.shareuuid,
        groupuuid: checkJsonData.groupuuid,
      },
    });
    const getUserOfGroupRes = await this.usertogroupRepository.findOne({
      where: {
        useruuid: useruuid,
        groupuuid: checkJsonData.shareuuid,
      },
    });
    if (checkRes === null && getUserOfGroupRes === null) {
      return true;
    } else {
      return false;
    }
  }
  async getSendShareItemByGroup(groupuuid: string) {
    const sendGroupToShareList = await this.groupToShareRepository.find({
      where: {
        groupuuid: groupuuid,
        type: 'send',
      },
    });
    const shareuuids = sendGroupToShareList.map((item) => item.shareuuid);
    const result = await Promise.all(
      shareuuids.map((uuid) => this.getShareItemById(uuid)),
    );
    return result;
  }
  async getReceiveShareItemByGroup(groupuuid: string) {
    const sendGroupToShareList = await this.groupToShareRepository.find({
      where: {
        groupuuid: groupuuid,
        type: 'receive',
      },
    });
    const shareuuids = sendGroupToShareList.map((item) => item.shareuuid);

    if (shareuuids.length === 0) {
      return [];
    }
    const shareItems = await this.getShareItemsByIds(shareuuids);
    const groupIds = shareItems.map((item) => item.belong);
    const groups = await this.groupRepository.find({
      where: { group_id: In(groupIds) },
    });
    const groupMap = new Map(
      groups.map((group) => [group.group_id, group.group_name]),
    );
    const result = shareItems.map((shareInfo) => ({
      ...shareInfo,
      belong: groupMap.get(shareInfo.belong) || 'Unknown',
    }));
    return result;
  }
  async removeShareItemOfGroupById(id: string) {
    try {
      const delList = await this.groupToShareRepository.find({
        where: { shareuuid: id },
      });
      // 并行删除所有 UserToShareItem
      await Promise.all(
        delList.map((item) =>
          this.groupToShareRepository.delete({ id: item.id }),
        ),
      );

      // 删除 shareRepository 中的项
      await this.shareRepository.delete({ id: id });

      return '删除成功';
    } catch (error) {
      console.error('删除失败:', error);
      return '删除失败';
    }
  }
  removeGroupToShareItemByShareId(removeData: {
    shareuuid: string;
    groupuuid: string;
  }) {
    try {
      return this.groupToShareRepository.delete({
        shareuuid: removeData.shareuuid,
        groupuuid: removeData.groupuuid,
        type: 'receive',
      });
    } catch (error) {
      return `删除失败`;
    }
  }
}
